package com.alpha.task.service.impl;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.DateBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alpha.mybaits.mapper.TcSystemConfigMapper;
import com.alpha.mybaits.mapper.TcTaskInfoMapper;
import com.alpha.mybaits.model.TcTaskInfo;
import com.alpha.task.constant.CountDownConstant;
import com.alpha.task.job.CountDownJob;
import com.alpha.task.service.CountDownService;


@Service
public class CountDownServiceImpl implements CountDownService {

	protected Logger logger =  Logger.getLogger(getClass().getName());
	
	@Autowired
	private SchedulerFactoryBean schedulerFactoryBean;
	
	@Autowired
	private TcTaskInfoMapper taskInfoMapper;
	
	@Autowired
	private  TcSystemConfigMapper systemConfigMapper;
	
	@Override
	public void toStartUnloadTask() throws SchedulerException {
		logger.info("CountDownServiceImpl toStartUnloadTask  start -------> ");
		List<TcTaskInfo> taskList = findUnloadTask(TcTaskInfo.NOT_TRIGGER);
		logger.info("task list size :" + taskList.size());
		
		if(taskList == null || taskList.isEmpty()){
			logger.info("toStartUnloadTask :  task list is empty ");
			return;
		}
		logger.info("toStartUnloadTask total : " + taskList.size());
		for(TcTaskInfo task : taskList){
			this.taskJobBegin(task);
		}
		
		logger.info("toStartUnloadTask end <-------");
		
	}
	
	
	@Override
	public void startTaskById(Long id) throws SchedulerException {
		logger.info("CountDownServiceImpl startTaskById ");
		
		TcTaskInfo Tti = new TcTaskInfo();
		Tti.setStatus(TcTaskInfo.NOT_TRIGGER);
		Tti.setId(id);
		
		TcTaskInfo task = taskInfoMapper.selectOne(Tti);
		this.taskJobBegin(task);
		
	}
	
	@Override
	public void toStartUnTriggerTask() throws SchedulerException {
		
		logger.info("CountDownServiceImpl toStartUnTriggerTask ");
		
		List<TcTaskInfo> allTask = new LinkedList<TcTaskInfo>();
		
		List<TcTaskInfo> taskList = this.findUnloadTask(TcTaskInfo.NOT_TRIGGER);
		
		if(taskList != null && !taskList.isEmpty()){
			allTask.addAll(taskList);
		}
		
		List<TcTaskInfo> triggerList = this.findLoadedTriggerTask();

		if(triggerList != null && !triggerList.isEmpty()){
			allTask.addAll(triggerList);
		}
		
		logger.info("CountDownServiceImpl  UnTrigger Task  list size : "+ allTask.size());
		
		if(!allTask.isEmpty()){
			Date now = new Date();
			
			for(TcTaskInfo task : allTask){
				if(task.getTaskDate().before(now)){
					Date executeTime = DateBuilder.nextGivenSecondDate(null, 1); 
					task.setTaskDate(executeTime);
				}
				
				this.taskJobBegin(task);
			}
		}
		
		
	}

	
	@Override
	@Transactional
	public void modifyAndStartTask() throws SchedulerException {
		logger.info("CountDownServiceImpl modifyAndStartTask ");
		
		List<TcTaskInfo> taskList = this.findUnloadTask(TcTaskInfo.MODIFY_TRIGGER);
		if(taskList == null || taskList.isEmpty()){
			logger.info("toStartUnloadTask :  task list is empty ");	
			return;
		}
		logger.info("Task total : " + taskList.size());
		
		for(TcTaskInfo task : taskList){
			this.toDeleteTask(task);
		}
		//开始加载未加载的任务
		this.toStartUnloadTask();
		
	}
	
	/**
	 * 移除任务,并更新状态
	 * @param task
	 * @throws SchedulerException
	 */
	private void toDeleteTask(TcTaskInfo task) throws SchedulerException {
		Scheduler sched = schedulerFactoryBean.getScheduler();
		String jobId = this.createJobId(task);
		JobKey jobKey = new JobKey(jobId,CountDownConstant.TASK_GROUP);
		if(sched.checkExists(jobKey)){
			sched.deleteJob(jobKey);
			task.setStatus(TcTaskInfo.STOPPED_TRIGGER);
			taskInfoMapper.updateByPrimaryKeySelective(task);
		}
	}


	private List<TcTaskInfo> findLoadedTriggerTask() {
		TcTaskInfo Tti = new TcTaskInfo();
		Tti.setStatus(TcTaskInfo.LOADED_TASK);
		return taskInfoMapper.select(Tti);
	}


	/**
	 * 任务调度开始
	 * @param task
	 * @throws SchedulerException 
	 */
	private void taskJobBegin(final TcTaskInfo task) throws SchedulerException {
		Scheduler sched = schedulerFactoryBean.getScheduler();
		
		String jobId= this.createJobId(task);
		
		String triggerId=  CountDownConstant.TASK_NAME + "_" + task.getId();
		
        //绑定任务  
        JobDetail job = JobBuilder.newJob(CountDownJob.class).withIdentity(jobId, CountDownConstant.TASK_GROUP).build();  
        job.getJobDataMap().put(CountDownConstant.TASK_JOB_OBJECT, task);
        job.getJobDataMap().put(CountDownConstant.TASK_INFO_MAPPER, taskInfoMapper);
        job.getJobDataMap().put(CountDownConstant.TASK_INFO_SYSTEM_CONFIG, systemConfigMapper); 
        //触发器  
        SimpleTrigger trigger = TriggerBuilder.newTrigger()   
            .withIdentity(triggerId, CountDownConstant.TRIGGER_GROUP)  
            .startAt(task.getTaskDate()) 
            .withSchedule(SimpleScheduleBuilder.simpleSchedule()).build();
        sched.scheduleJob(job, trigger); 
        
        //开始任务
        sched.start();  
        //更新状态
        task.setStatus(TcTaskInfo.LOADED_TASK);
		taskInfoMapper.updateByPrimaryKeySelective(task);
	}
	
	/**
	 * 根据task任务
	 * @param task
	 * @return
	 */
	private String createJobId(TcTaskInfo task) {
		return task.getTaskModelName() + "_" + task.getId();
	}


	/**
	 * 获取未加载的任务
	 * @return
	 */
	private List<TcTaskInfo> findUnloadTask(Integer status) {
		TcTaskInfo Tti = new TcTaskInfo();
		Tti.setStatus(status);
		return taskInfoMapper.select(Tti);
	}




	
	

}
